package cn.itsource.ymcc.strategy;

import cn.itsource.ymcc.constants.BaseConstants;
import cn.itsource.ymcc.domain.PayFlow;
import cn.itsource.ymcc.dto.AlipayNotifyDto;
import cn.itsource.ymcc.dto.NotifyDto;
import cn.itsource.ymcc.exception.GlobleException;
import cn.itsource.ymcc.service.IPayFlowService;
import cn.itsource.ymcc.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.easysdk.factory.Factory;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

//阿里支付结果处理
@Component("AlipayNotifyStrategy")
@Slf4j
public class AlipayNotifyStrategy implements PayNotifyStrategy {


    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private IPayFlowService payFlowService;

    @Override
    public String notify(NotifyDto dto) {
        AssertUtil.isTrue(suport(dto.getClass()),"不支持对象类型" );
        AlipayNotifyDto alipayNotifyDto = (AlipayNotifyDto)dto;

        try {
            //验证签名
            Boolean signSuccess = Factory.Payment.Common().verifyNotify(JSON.parseObject(JSON.toJSONString(alipayNotifyDto),Map.class));
            AssertUtil.isTrue(signSuccess,"验证签名失败");
        } catch (Exception e) {
            e.printStackTrace();
        }

        log.info("支付结果参数 {}",alipayNotifyDto);
        //交易中，不处理
        if(alipayNotifyDto.isTradeWit()){
            log.info("待支付");
            return "ERROR";
        }

        //交易号
        AssertUtil.isNotEmpty(alipayNotifyDto.getOut_trade_no(),"无效的交易单号");

        //幂等处理
        PayFlow payFlow = payFlowService.selectByOutTradeNo(((AlipayNotifyDto) dto).getOut_trade_no());

        AssertUtil.isNull(payFlow,"订单已经被处理");

        //通知支付结果，采用MQ
        Message<String> message = MessageBuilder.withPayload(JSON.toJSONString(alipayNotifyDto)).build();

        //发送消息
        Map<String,Object> args = new HashMap<>();
        args.put("SaveFlow","true");
        SendResult mqSend2CourseResult = rocketMQTemplate
                .sendMessageInTransaction(
                        BaseConstants.PayMQ.TX_PAY_RESULT_GROUP,
                        BaseConstants.PayMQ.TOPIC_PAY_RESULT + ":" + BaseConstants.PayMQ.TAGS_BUYCOURSE_RESULT_2ORDER,
                message,args);

        if(mqSend2CourseResult.getSendStatus() != SendStatus.SEND_OK ){
            throw new GlobleException("支付结果，事务消息发送到课程队列失败");
        }

        args.put("SaveFlow","false");
        SendResult mqSend2OrderResult = rocketMQTemplate
                .sendMessageInTransaction(
                        BaseConstants.PayMQ.TX_PAY_RESULT_GROUP,
                        BaseConstants.PayMQ.TOPIC_PAY_RESULT + ":" + BaseConstants.PayMQ.TAGS_BUYCOURSE_RESULT_2COURSE,
                        message,args);

        if(mqSend2OrderResult.getSendStatus() != SendStatus.SEND_OK ){
            throw new GlobleException("支付结果，事务消息发送到订单队列失败");
        }

        //发送成功，响应“SUCCESS”给支付宝
        return "SUCCESS";
    }

    @Override
    public boolean suport(Class clz) {
        return clz.getName().equals(AlipayNotifyDto.class.getName());
    }
}
